package rpc

import (
	"context"
	"database/sql"
	"encoding/json"
	"github.com/heroiclabs/nakama-common/runtime"
	"nakama_poker/biz"
	"nakama_poker/utils"
)

func generateRoomCode(ctx context.Context, nk runtime.NakamaModule) (string, error) {
	var roomCode string
	for {
		roomCode = utils.GenerateRandomCode(6)

		// 检查是否已存在（避免冲突）
		existCheck, err := nk.StorageRead(ctx, []*runtime.StorageRead{{
			Collection: "room_codes",
			Key:        roomCode,
			UserID:     "",
		}})
		if err != nil {
			return "", err
		}
		if len(existCheck) == 0 {
			break // 找到未被使用的房号
		}
	}
	return roomCode, nil
}

func CreatePokerGame(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {

	var params map[string]interface{}
	if err := json.Unmarshal([]byte(payload), &params); err != nil {
		return "", biz.NewError(biz.ErrUnmarshalPayload, err)
	}
	// 1. 自动生成唯一房间号
	roomCode, err := generateRoomCode(ctx, nk)
	if err != nil {
		return "", biz.NewError(biz.ErrUnknown, err)
	}
	creatorId, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
	if !ok {
		return "", biz.NewError(biz.ErrUnknown, err)
	}
	params["creatorId"] = creatorId
	// 2. 创建比赛
	matchId, err := nk.MatchCreate(ctx, "Poker", params)
	if err != nil {
		logger.Error("[MatchCreate] error: ", err.Error())
		return "", err
	}

	roomMap := map[string]interface{}{
		"matchId": matchId,
	}

	roomMapBytes, err := json.Marshal(roomMap)
	if err != nil {
		return "", biz.NewError(biz.ErrMarshalPayload, err)
	}

	// 3. 储存房号 → match_id 映射
	storageObj := &runtime.StorageWrite{
		Collection: "room_codes",
		Key:        roomCode,
		Value:      string(roomMapBytes),
	}
	if _, err := nk.StorageWrite(ctx, []*runtime.StorageWrite{storageObj}); err != nil {
		return "", err
	}

	return biz.Response(
		&biz.H{
			"room_code": roomCode,
			"match_id":  matchId,
		},
	)
}

func GetPokerGame(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
	var params map[string]interface{}
	if err := json.Unmarshal([]byte(payload), &params); err != nil {
		return "", biz.NewError(biz.ErrUnmarshalPayload, err)
	}
	roomCodeValue, ok := params["room_code"]
	if !ok {
		return "", biz.NewError(biz.ErrMissRoomCode, nil)
	}
	roomCode, ok := roomCodeValue.(string)
	if !ok {
		return "", biz.NewError(biz.ErrInvalidRoomCode, nil)
	}

	// 检查是否已存在（避免冲突）
	objects, err := nk.StorageRead(ctx, []*runtime.StorageRead{{
		Collection: "room_codes",
		Key:        roomCode,
	}})

	if err != nil || len(objects) == 0 {
		return "", biz.NewError(biz.ErrNotFoundRoom, err)
	}
	roomObject := objects[0]

	var result map[string]interface{}
	if err := json.Unmarshal([]byte(roomObject.Value), &result); err != nil {
		return "", biz.NewError(biz.ErrNotFoundRoom, err)
	}
	matchId, ok := result["matchId"]
	if !ok {
		return "", biz.NewError(biz.ErrNotFoundRoom, err)
	}
	return biz.Response(
		&biz.H{
			"match_id": matchId,
		},
	)
}
